#!/bin/bash

# See http://blog.carbonfive.com/2011/05/04/automated-ad-hoc-builds-using-xcode-4/ for discussion.

# command line OTA distribution references and examples
# http://nachbaur.com/blog/how-to-automate-your-iphone-app-builds-with-hudson
# http://nachbaur.com/blog/building-ios-apps-for-over-the-air-adhoc-distribution
# http://blog.octo.com/en/automating-over-the-air-deployment-for-iphone/
# http://www.neat.io/posts/2010/10/27/automated-ota-ios-app-distribution.html

project_dir=`pwd`
#workspace="MyProject.xcworkspace"
#scheme="Ad Hoc"
project_app="ActiveDeck.app"
project_ipa="ActiveDeck.ipa"
mobileprovision="$project_dir/ActiveDeck_Ad_Hoc.mobileprovision"
provisioning_profile="iPhone Distribution: Three Byte Intermedia, Inc."
info_plist="$project_dir/ActiveDeck-Info.plist"
info_plist=$(ls $info_plist | sed -e 's/\.plist//')
#keychain="teamcity_builds"
#keychain_password="secret"
teamcity_host="192.168.60.111"
#display_image_name="Icon-57.png"
#full_size_image_name="Icon-512.png"

#environment_plist="acceptance.plist"
#environment_plist_path="MyApp"

function failed()
{
    local error=${1:-Undefined error}
    echo "Failed: $error" >&2
    exit 1
}

function validate_keychain()
{
  # unlock the keychain containing the provisioning profile's private key and set it as the default keychain
  security unlock-keychain -p "$keychain_password" "$HOME/Library/Keychains/$keychain.keychain"
  security default-keychain -s "$HOME/Library/Keychains/$keychain.keychain"
  
  #describe the available provisioning profiles
  echo "Available provisioning profiles"
  echo security find-identity -p codesigning -v
  security find-identity -p codesigning -v

  #verify that the requested provisioning profile can be found
  echo security find-certificate -a -c "$provisioning_profile"
  (security find-certificate -a -c "$provisioning_profile" -Z | grep ^SHA-1) || failed provisioning_profile  
}

function describe_sdks()
{
  #list the installed sdks
  echo "Available SDKs"
  echo xcodebuild -showsdks
  xcodebuild -showsdks  
}

function describe_workspace()
{
  #describe the project workspace
  echo "Available schemes"
  echo xcodebuild -list -workspace $workspace
  xcodebuild -list -workspace $workspace
}

function set_environment()
{
  echo cp -v "$environment_plist_path/$environment_plist" "$environment_plist_path/environment.plist"
  cp -v "$environment_plist_path/$environment_plist" "$environment_plist_path/environment.plist" || failed environment
}

function build_app()
{
  #build the app
  echo xcodebuild -verbose -workspace "$workspace" -scheme "$scheme" -sdk iphoneos -configuration Release clean build
  #xcodebuild -verbose -workspace "$workspace" -scheme "$scheme" -sdk iphoneos -configuration Release clean build || failed xcodebuild
  xcodebuild -verbose -project "ActiveDeck.xcodeproj" || failed xcodebuild

  #locate project's DerivedData directory
#project_derived_data=`ls -ut1 $HOME/Library/Developer/Xcode/DerivedData | head -n 1`
  #locate the .app file
#ls -1 "$HOME/Library/Developer/Xcode/DerivedData/$project_derived_data/Build/Products/Release-iphoneos/"
#  project_app=`ls -1 "$HOME/Library/Developer/Xcode/DerivedData/$project_derived_data/Build/Products/Release-iphoneos/" | grep ".*\.app$"`
  echo "Built $project_app"

  #copy app and dsym files to working directory
#  echo cp -R "$HOME/Library/Developer/Xcode/DerivedData/$project_derived_data/Build/Products/Release-iphoneos/$project_app" $project_dir
#  cp -R "$HOME/Library/Developer/Xcode/DerivedData/$project_derived_data/Build/Products/Release-iphoneos/$project_app" $project_dir
#  echo cp -R "$HOME/Library/Developer/Xcode/DerivedData/$project_derived_data/Build/Products/Release-iphoneos/$project_app.dSYM" $project_dir
#  cp -R "$HOME/Library/Developer/Xcode/DerivedData/$project_derived_data/Build/Products/Release-iphoneos/$project_app.dSYM" $project_dir
  
  #relink CodeResources, xcodebuild does not reliably construct the appropriate symlink
#  rm "$project_app/CodeResources"
#  ln -s "$project_app/_CodeSignature/CodeResources" "$project_app/CodeResources"
}

function sign_app()
{
  #sign build for distribution and package as a .ipa
  echo xcrun -verbose -sdk iphoneos PackageApplication "$project_dir/build/Release-iphoneos/$project_app" -o "$project_dir/build/Release-iphoneos/$project_ipa" --sign "$provisioning_profile" --embed "$mobileprovision"
  xcrun -verbose -sdk iphoneos PackageApplication "$project_dir/build/Release-iphoneos/$project_app" -o "$project_dir/build/Release-iphoneos/$project_ipa" --sign "$provisioning_profile" --embed "$mobileprovision" || failed codesign  
}

function verify_app()
{
  #verify the resulting app
  echo codesign -d --file-list - "$project_dir/$project_app"
  codesign -d --file-list - "$project_dir/$project_app" || failed verification  
}

function build_ota_plist()
{
  cat << EOF > $project_app.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>items</key>
  <array>
    <dict>
      <key>assets</key>
      <array>
        <dict>
          <key>kind</key>
          <string>software-package</string>
          <key>url</key>
          <string>http://activedeck.3-byte.com/ios/$project_ipa</string>
        </dict>
      </array>
      <key>metadata</key>
      <dict>
        <key>bundle-identifier</key>
        <string>$bundle_identifier</string>
        <key>bundle-version</key>
        <string>$short_version_string</string>
        <key>kind</key>
        <string>software</string>
        <key>title</key>
        <string>ActiveDeck</string>
      </dict>
    </dict>
  </array>
</dict>
</plist>
EOF
}

#extract settings from the Info.plist file
#short_version_string=$(defaults read "$info_plist" CFBundleShortVersionString)
short_version_string=$(defaults read "$info_plist" CFBundleVersion)
bundle_identifier=$(defaults read "$info_plist" CFBundleIdentifier)

#validate_keychain
describe_sdks
#describe_workspace
#set_environment
build_app
sign_app
#verify_app
build_ota_plist